"""
@author: 江同学呀
@file: keyword_field.py
@date: 2023/8/22 19:45
@desc:
    https://www.elastic.co/guide/en/elasticsearch/reference/7.17/keyword.html

    The keyword family, including keyword, constant_keyword, and wildcard.
    关键字系列，包括 keyword 、 constant_keyword 和 wildcard 。
"""


from abc import ABC
from typing import Type, Union, Dict, List

from espc.common.field_common import IndexOptions, Similarity
from espc.orm.model.base.base import _Base
from espc.orm.model.mapping.field.field_attribute import EagerGlobalOrdinalsAttribute, FieldsAttribute, BoostAttribute, \
    DocValuesAttribute, IndexAttribute, IgnoreAboveAttribute, IndexOptionsAttribute, MetaAttribute, NormsAttribute, \
    ScriptAttribute, OnScriptErrorAttribute, NormalizerAttribute, SimilarityAttribute, NullValueAttribute, \
    TimeSeriesDimensionAttribute, StoreAttribute, SplitQueriesOnWhitespaceAttribute
from espc.orm.model.mapping.field.base_field.base_string_field import _BaseStringField
from espc.utils.build_add_attr import build_add_attr


class KeywordField(
    _BaseStringField, BoostAttribute, DocValuesAttribute, EagerGlobalOrdinalsAttribute, FieldsAttribute, StoreAttribute,
    IgnoreAboveAttribute, IndexAttribute, IndexOptionsAttribute, MetaAttribute, NormsAttribute, OnScriptErrorAttribute,
    ScriptAttribute, SimilarityAttribute, NormalizerAttribute, NullValueAttribute, TimeSeriesDimensionAttribute,
    SplitQueriesOnWhitespaceAttribute, ABC
):
    """
    关键词 字段
    """
    _field_type: str = "keyword"

    def __init__(
            self, field_name: str = None, value: str = None, default: str = None, boost: float = None,
            split_queries_on_whitespace: bool = None, eager_global_ordinals: bool = None, doc_values: bool = None,
            null_value: str = None, normalizer: str = None, script: str = None, store: bool = None, meta: Dict = None,
            fields: Union[_BaseStringField, List[_BaseStringField]] = None, norms: bool = None,
            similarity: Union[str, Similarity] = None, index: bool = None, ignore_above: int = None,
            time_series_dimension: bool = None, index_options: Union[str, IndexOptions] = None,
            on_script_error: str = None
    ):
        super(KeywordField, self).__init__(
            field_name=field_name, value=value, default=default, boost=boost, doc_values=doc_values, index=index,
            ignore_above=ignore_above, store=store, meta=meta, eager_global_ordinals=eager_global_ordinals,
            fields=fields, null_value=null_value, on_script_error=on_script_error, script=script, similarity=similarity,
            normalizer=normalizer, norms=norms, time_series_dimension=time_series_dimension,
            split_queries_on_whitespace=split_queries_on_whitespace, index_options=index_options,
        )
        return

    def __get__(self, instance: _Base, owner: Type["KeywordField"]) -> Union["KeywordField", str]:
        return super(KeywordField, self).__get__(instance=instance, owner=owner)

    def __set__(self, instance, value: str):
        super(KeywordField, self).__set__(instance=instance, value=value)
        return

    @build_add_attr
    def _build(self) -> Dict:
        mapping: Dict = {
            "type": self._field_type,
        }
        return mapping


class ConstantKeywordField(_BaseStringField, MetaAttribute, ABC):
    """
    常量关键词 字段
    """
    _field_type: str = "constant_keyword"

    def __init__(self, field_name: str = None, value: str = None, default: str = None, meta: Dict = None):
        super(ConstantKeywordField, self).__init__(field_name=field_name, value=value, default=default, meta=meta)
        return

    def __get__(self, instance: _Base, owner: Type["ConstantKeywordField"]) -> Union["ConstantKeywordField", str]:
        return super(ConstantKeywordField, self).__get__(instance=instance, owner=owner)

    def __set__(self, instance, value: str):
        super(ConstantKeywordField, self).__set__(instance=instance, value=value)
        return

    @build_add_attr
    def _build(self) -> Dict:
        mapping: Dict = {
            "type": self._field_type,
        }
        if self._value is not None:
            mapping["value"] = self._value
        return mapping


class WildcardField(_BaseStringField, IgnoreAboveAttribute, NullValueAttribute, ABC):
    """
    通配符 字段
    """
    _field_type: str = "wildcard"

    def __init__(
            self, field_name: str = None, value: str = None, default: str = None, meta: Dict = None,
            null_value: str = None, ignore_above: int = None
    ):
        super(WildcardField, self).__init__(
            field_name=field_name, value=value, default=default, meta=meta, null_value=null_value,
            ignore_above=ignore_above
        )
        return

    def __get__(self, instance: _Base, owner: Type["WildcardField"]) -> Union["WildcardField", str]:
        return super(WildcardField, self).__get__(instance=instance, owner=owner)

    def __set__(self, instance, value: str):
        super(WildcardField, self).__set__(instance=instance, value=value)
        return

    @build_add_attr
    def _build(self) -> Dict:
        mapping: Dict = {
            "type": self._field_type,
        }
        return mapping









